package com.paireach.bw.http;

import android.content.Context;
import android.util.Log;
import com.android.volley.AuthFailureError;
import com.android.volley.DefaultRetryPolicy;
import com.android.volley.ParseError;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.TimeoutError;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.HurlStack;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.paireach.bw.event.HttpErrorEvent;
import com.paireach.bw.event.HttpSuccessEvent;
import org.greenrobot.eventbus.EventBus;
import org.json.JSONObject;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;


/**
 * 使用Volley的一个网路请求
 */
public class MainRequest {
    private RequestQueue mQueue;
    private Context mContext;
    private static MainRequest self;

    /**
     * 获取MainRequest实例
     *
     * @return MainRequest的一个单例
     */
    public static MainRequest getInstance() {
        if (self == null) {
            self = new MainRequest();
        }
        return self;
    }

    private MainRequest() {
    }

    /**
     * 发布请求
     *
     * @param url 请求地址
     * @param map 传递的数据，map类型
     * @param tag 请求的tag
     */
    public void makeRequest(String url, Map<String, String> map, final RequestTag tag) {
        JsonObjectPostRequest jsonObjectPostRequest = new JsonObjectPostRequest(url, new Response.Listener<JSONObject>() {

            @Override
            public void onResponse(JSONObject response) {
                handleVolleySuccess(response.toString(), tag);
            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                handleVolleyError(error, tag);
            }
        }, map);
        jsonObjectPostRequest.setTag(tag);
        jsonObjectPostRequest.setRetryPolicy(new DefaultRetryPolicy(10 * 1000, 0, 0.0f));
        if (mQueue != null) {
            mQueue.add(jsonObjectPostRequest);
        } else {
            initRequestQueue(mContext);
            mQueue.add(jsonObjectPostRequest);
        }
    }

    /**
     * 发布请求，使用GET方法
     *
     * @param url 请求地址
     * @param tag 请求的tag
     */
    public void makeStringGetRequest(String url, final RequestTag tag) {
        StringRequest jsonObjectPostRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {

            @Override
            public void onResponse(String response) {
                handleVolleySuccess(response, tag);
            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                handleVolleyError(error, tag);
            }
        });
        jsonObjectPostRequest.setTag(tag);
        jsonObjectPostRequest.setRetryPolicy(new DefaultRetryPolicy(10 * 1000, 0, 0.0f));
        if (mQueue != null) {
            mQueue.add(jsonObjectPostRequest);
        } else {
            initRequestQueue(mContext);
            mQueue.add(jsonObjectPostRequest);
        }
    }

    /**
     * 发布请求，使用Post方法
     * @param url 请求地址
     * @param tag 请求的tag
     */
    public void makeStringPostRequest(String url, final Map<String, String> map, final RequestTag tag) {
        StringRequest jsonObjectPostRequest = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {

            @Override
            public void onResponse(String response) {
                handleVolleySuccess(response, tag);
            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                handleVolleyError(error, tag);
            }
        }) {
            @Override
            protected Map<String, String> getParams() throws AuthFailureError {

                return map;
            }
        };

        jsonObjectPostRequest.setTag(tag);
        jsonObjectPostRequest.setRetryPolicy(new DefaultRetryPolicy(10 * 1000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
        if (mQueue != null) {
            mQueue.add(jsonObjectPostRequest);
        } else {
            initRequestQueue(mContext);
            mQueue.add(jsonObjectPostRequest);
        }
    }


    /**
     * 初始化请求队列
     *
     * @param mContext 上下文
     */
    public void initRequestQueue(Context mContext) {
        this.mContext = mContext;
        if (mQueue == null) {
            HurlStack stack = new HurlStack() {
                @Override
                protected HttpURLConnection createConnection(URL url) throws IOException {
                    HttpURLConnection con = super.createConnection(url);
                    //主要是这行代码, 貌似是因为HttpClient的bug
                    con.setChunkedStreamingMode(0);
//                    con.setChunkedStreamingMode(1024*1024);
//                    con.setConnectTimeout(5000);
                    return con;
                }
            };
            mQueue = Volley.newRequestQueue(mContext, stack);
        }
    }

    private void handleVolleySuccess(String response, RequestTag tag) {
        Log.d("response", "response="+response);
        HttpSuccessEvent baseEvent = new HttpSuccessEvent();
        baseEvent.setJson(response);
        baseEvent.setRequestTag(tag);
        EventBus.getDefault().post(baseEvent);
    }

    private void handleVolleyError(VolleyError volleyError, RequestTag tag) {
        HttpErrorEvent errorEvent = new HttpErrorEvent();
        if (volleyError.networkResponse != null && volleyError.networkResponse.data != null) {
            int statusCode = volleyError.networkResponse.statusCode;
            byte[] htmlBodyBytes = volleyError.networkResponse.data;
            errorEvent.setErrorCode(statusCode);
            errorEvent.setErrorMessage(new String(htmlBodyBytes));
            errorEvent.setRequestTag(tag);
//            Log.w("volleyErr", new String(htmlBodyBytes));
            Log.w("volleyErr", "if-"+new String(htmlBodyBytes)+"-statusCode="+statusCode);
        } else {
            String err = volleyError.toString();
            errorEvent.setRequestTag(tag);
            Log.w("volleyErr", "else-"+new String(err));
            if (volleyError instanceof TimeoutError) {
                errorEvent.setErrorCode(100);
                errorEvent.setErrorMessage("网络异常，连接服务器超时");
            } else if (volleyError instanceof AuthFailureError) {
                errorEvent.setErrorCode(101);
                errorEvent.setErrorMessage("http认证失败");
            } else if (volleyError instanceof ParseError) {
                errorEvent.setErrorCode(101);
                errorEvent.setErrorMessage("返回数据解析失败");
            } else {
                errorEvent.setErrorCode(102);
                errorEvent.setErrorMessage("请求失败，请检查网络或服务器是否开启");
            }
        }
        EventBus.getDefault().post(errorEvent);
    }

    /**
     * 获取请求队列
     */
    public RequestQueue getmQueue() {
        return mQueue;
    }
}
